var httpServer = require('http').createServer(function (req, response) { /* Serve your static files */ });
httpServer.listen(8080);
var userFile = require("./User.js");
var User = userFile.User;
var gameBoardsFile = require("./GameBoards.js");
var GameBoards = gameBoardsFile.GameBoards;
var gameEngineFile = require("./GameEngine.js");
var GameEngine = gameEngineFile.GameEngine;
var nowjs = require("now");
var everyone = nowjs.initialize(httpServer);
var gameEngine = new GameEngine(GameBoards.getLevel1());
var gameStarted = false;

var disconnect = function () {
    var oldHost;
    var newHost;
    var playerRemoved;

    if (gameEngine != null) {
        if (this.now.user) {
            console.log(this.now.user.userName + " left");
            oldHost = gameEngine.getHost();
            playerRemoved = gameEngine.removeUser(this.now.user.id);
        }
    }

    if (gameEngine.getNumberOfUsers() > 0) {
        everyone.now.userLeft(this.now.user);

        newHost = gameEngine.getHost();

        if (oldHost && (oldHost.id != newHost.id)) {
            console.log(newHost.userName + " is now the host");
            everyone.now.hostGranted(newHost.id);
        }
    }
    else {
        restartGame(true);
    }
};

nowjs.on("disconnect", disconnect);

everyone.now.login = function () {
    this.now.user.userName = htmlEncode(this.now.user.userName);
    var user = new User(this.now.user);
    if (gameEngine.isGameOpen()) {
        console.log("Adding User");
        var addedUser = gameEngine.addUser(user);
        console.log(addedUser);
        if (addedUser) {
            var host = gameEngine.getHost();

            everyone.now.updateUsers(gameEngine.getUsers());
            console.log(user.userName + " joined the game");
            this.now.loginSuccess(gameEngine.getUpdatesForNewPlayer(), user.id);
            everyone.now.userJoined(user);

            if (host.id == user.id) {
                everyone.now.hostGranted(user.id);
            }
        }
        else {
            this.now.loginFailure(this.now.user.userName + " is already in use.");
        }
    }
    else {
        this.now.loginFailure("Game is locked.");
    }
};

everyone.now.startGame = function (alienSpeed, hunterSpeed, botSpeed, aiAlienBots) {
    if (!gameStarted && this.now.user.id == gameEngine.getHost().id && !isNaN(alienSpeed) && !isNaN(hunterSpeed)) {
        var alienInterval = (1000 / alienSpeed);
        var hunterInterval = (1000 / hunterSpeed);
        var botInterval = (1000 / botSpeed);

        gameStarted = true;
        gameEngine.gameBoardUpdated = gameBoardUpdated;
        gameEngine.playerDied = playerDied;
        gameEngine.gameOver = gameOver;

        for (i = 0; i < aiAlienBots; i++) {
            user = new User();
            user.userName = "Bot " + (i + 1);
            user.alien = true;
            user.tokenColor = null;
            user.bot = true;
            gameEngine.addUser(user);
            everyone.now.userJoined(user);
        }
        everyone.now.updateUsers(gameEngine.getUsers());

        gameEngine.startGame(alienInterval, hunterInterval, botInterval);
        gameEngine.lockGame();
        everyone.now.gameStarted();
        console.log("Game Started");
        everyone.now.gameLocked();
        console.log("Game Locked");
    }
};

everyone.now.restartGame = function () {
    if (gameStarted && this.now.user.id == gameEngine.getHost().id) {
        restartGame(true);
    }
};

everyone.now.lockGame = function () {
    gameEngine.lockGame();
    everyone.now.gameLocked();
    console.log("Game Locked");
};

everyone.now.unlockGame = function () {
    gameEngine.unlockGame();
    everyone.now.gameUnlocked();
    console.log("Game Unocked");
};

everyone.now.generateBoard = function (fillFactor) {
    if (!gameStarted && this.now.user.id == gameEngine.getHost().id) {
        console.log("Generating Random Board");
        gameEngine.generateBoard(fillFactor);
        gameBoardUpdated(gameEngine.getUpdatesForNewPlayer(), false, false);
    }
};

everyone.now.generateLevel = function (levelNumber) {
    if (!gameStarted && this.now.user.id == gameEngine.getHost().id && (levelNumber == 1 || levelNumber == 2 || levelNumber == 3)) {
        console.log("Generating Level #" + levelNumber);
        gameEngine.generateLevel(levelNumber);
        gameBoardUpdated(gameEngine.getUpdatesForNewPlayer(), false, false);
    }
};

everyone.now.moveUp = function () {
    var user = gameEngine.getUser(this.now.user.id);
    if (user) {
        user.setQueuedMove(User.MOVE_UP);
    }
};

everyone.now.moveRight = function () {
    var user = gameEngine.getUser(this.now.user.id);
    if (user) {
        user.setQueuedMove(User.MOVE_RIGHT);
    }
};

everyone.now.moveDown = function () {
    var user = gameEngine.getUser(this.now.user.id);
    if (user) {
        user.setQueuedMove(User.MOVE_DOWN);
    }
};

everyone.now.moveLeft = function () {
    var user = gameEngine.getUser(this.now.user.id);
    if (user) {
        user.setQueuedMove(User.MOVE_LEFT);
    }
};

everyone.now.sendMessage = function (message) {
    everyone.now.messageReceived(this.now.user, htmlEncode(message));
};

function restartGame(notify) {
    if (notify && everyone.now.gameRestarted) {
        console.log("Game Restarted");
        everyone.now.gameRestarted();
    }
    gameEngine = new GameEngine(GameBoards.getLevel1());
    if (User.HunterIdCounter > 1000000 || User.AlienIdCount < -1000000) {
        User.resetIds();
    }
    gameStarted = false;
}

function gameBoardUpdated(updates, playerChanges, alienUpdate) {
    if (playerChanges) {
        everyone.now.updateUsers(gameEngine.getUsers());
    }
    if (true || updates.length > 0) {
        everyone.now.gameBoardUpdated(updates, alienUpdate);
    }
}

function playerDied(userId) {
    console.log(userId + " has died");
    everyone.now.playerDied(userId);
}

function gameOver(aliensWon) {
    console.log("game over: " + (aliensWon ? "aliens" : "hunters") + " won!");
    everyone.now.gameOver(aliensWon);
    restartGame(false);
}

function htmlEncode(value) {
    if (value) {
        return value.replace(/&/g, '&amp;').
        replace(/</g, '&lt;').
        replace(/"/g, '&quot;').
        replace(/'/g, '&#039;');
    }
    else {
        return value;
    }
}